#pragma once

#include <mosquitto.h>
#include <iostream>
#include <string>
#include <chrono>

class MqttClient{
public:
    MqttClient(const std::string &client_id,
               const std::string &host,
               int port,
               const std::string &username = "",
               const std::string &password = "",
               int keepalive = 10);
    ~MqttClient();

    bool connect();
    void stop();
    bool publish(const std::string &topic, const std::string &payload, int qos = 0, bool retain = false);
    bool subscribe(const std::string &topic, int qos = 0);

    /**
     * 这两个函数会在静态函数中调用（实现成员函数回调的一种方式）
     * 同时，这两个函数用virtual修饰，是虚函数，在子类中可以重写这两个函数。
    */
    virtual void onConnect(int rc);
    virtual void onMessage(const std::string &topic ,const std::string & payload);
private:
    /**
     * 成员变量说明：
     *  - mosq_ mqtt客户端的句柄
     *  - client_id_ mqtt客户端的唯一标识
     *  - host、prot mqtt服务器ip和端口号
     *  - username、password 服务器的名称和密码用于登录
     *  - keepalive 心跳间隔
    */
    struct mosquitto *mosq_ = nullptr;
    std::string client_id_, host_, username_, password_;
    int port_, keepalive_;

    static void on_connect_static(struct mosquitto *mosq, void *userdata, int rc);
    static void on_message_static(struct mosquitto *mosq, void *userdata, const struct mosquitto_message *msg);
};